#Lightwave object parser

import os, sys
from Sanae3D.lib.StructReader import StructReader
from Sanae3D.lib.ModelObject import Model3D

class Lightwave_obj(Model3D):
    
    def __init__(self, obj3D=None, outFile=None, inFile=None):
        
        super(Lightwave_obj,self).__init__("LWO")
        self.obj3D = obj3D
        self.inFile = inFile
        self.outFile = outFile
        self.tags = []
        
    def read_name(self):
        
        name = ""
        char = self.inFile.read_char()
        while char != "\x00":
            name = ''.join([name, char])
            char = self.inFile.read_char()
        
        if (len(name) + 1) % 2 != 0:
            self.inFile.read_byte()
        return name
    
    def parse_tags(self, chunk):
        
        sectLen = self.inFile.tell() + chunk
        while self.inFile.tell() != sectLen:
            self.tags.append(self.read_name())
                             
        print self.tags
    
    def parse_blok(self, chunk):
        
        sectEnd = self.inFile.tell() + chunk
        while self.inFile.tell() != sectEnd:
            tag = self.inFile.read_string(4)
            sectLen = self.inFile.read_short(end=1)
            self.inFile.seek(sectLen, 1)
    
    def parse_surf(self, chunk):
        
        matNum = self.mat_count()
        self.create_material(matNum)
        
        sectEnd = self.inFile.tell() + chunk
        name = self.read_name()
        self.add_material_name(matNum, name)
        
        self.inFile.seek(2, 1)
        
        while self.inFile.tell() != sectEnd:
            tag = self.inFile.read_string(4)
            sectLen = self.inFile.read_short(end=1)
            if tag == "BLOK":
                self.parse_blok(sectLen)
            elif tag == "COLR":
                r, g, b = self.inFile.read_float(3, end=1)
                index = self.inFile.read_short()
                self.add_rgba(matNum, [r, g, b, 0])
            else:
                self.inFile.seek(sectLen, 1)
                
    def parse_PTAG(self, meshName, numFaces, chunk):
        '''Associates tags of a given type with polygons in the
        most recent POLS chunk'''
    
    def parse_vertices(self, meshName, chunk):
        
        numVerts = chunk / 12
        verts = self.inFile.read_float(numVerts * 3, end=1)
        for i in xrange(0, numVerts * 3, 3):
            coords = verts[i:i+3]
            
            self.create_vertex(meshName, i / 3)
            self.add_coords(meshName, i / 3, coords)
        
    def parse_POLS(self, meshName, chunk):
        
        faceNum = 0
        start = self.inFile.tell()
        sectEnd = start + chunk   #from documentation
        
        tag = self.inFile.read_string(4)
        while self.inFile.tell() != sectEnd:
            numIndex = self.inFile.read_short(end=1)
            verts = self.inFile.read_short(numIndex, end=1)
                
            self.create_face(meshName, faceNum)
            self.add_face_verts(meshName, faceNum, verts)
            faceNum += 1
        
    def parse_file(self):
        '''Main parser method. Can be replaced'''
        
        meshName = "test"
        self.create_object(meshName)
        
        self.inFile.read_string(4)
        fsize = self.inFile.read_long(end=1) + 8
        lwoType = self.inFile.read_string(4)
        while self.inFile.tell() != fsize:
            tag = self.inFile.read_string(4)
            print tag
            chunkLen = self.inFile.read_long(end=1)
            if tag == "TAGS":
                self.parse_tags(chunkLen)
            elif tag == "LAYR":
                self.inFile.seek(chunkLen, 1)
            elif tag == "PNTS":
                self.parse_vertices(meshName, chunkLen)
            elif tag == "POLS":
                numFaces = self.parse_POLS(meshName, chunkLen)
            elif tag == "BBOX":
                self.inFile.seek(chunkLen, 1)
            elif tag == "VMAP":
                self.inFile.seek(chunkLen, 1)
            elif tag == "PTAG":
                self.inFile.seek(chunkLen, 1)
            elif tag == "CLIP":
                self.inFile.seek(chunkLen, 1)
            elif tag == "VMAD":
                self.inFile.seek(chunkLen, 1)
            elif tag == "SURF":
                self.parse_surf(chunkLen)

        
def read_file(path):
    '''Read the file'''
    
    openFile = StructReader(open(path, 'rb'))
    obj = Lightwave_obj(inFile=openFile)
    obj.parse_file()
    openFile.close()
    return obj

def write_file(path):
    
    pass

def definitions():
    '''Return the header, extension, and a description of the format'''
    
    return "FORM", "LWO", "Lightwave Object"

if __name__ == '__main__':
    
    file1 = "SoccerBall-Normal.lwo"
    file2 = "orange.lwo"
    read_file(file2)